#ifndef _RTP_H_
#define _RTP_H_

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <arpa/inet.h>


#define RTP_VESION              2
#define RTP_PAYLOAD_TYPE_H264   96
#define RTP_HEADER_SIZE         12
#define RTP_MAX_PKT_SIZE       1500
#define RTP_PACKET_SIZE          500000
/* 因为网络字节顺序NBO 和 主机字节顺序的原因 所以是高位在前
 * RTP Heaeder占用最少12个字节，最多72个字节
 *    0                   1                   2                   3
 *    7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *   |V=2|P|X|  CC   |M|     PT      |       sequence number         |
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *   |                           timestamp                           |
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *   |           synchronization source (SSRC) identifier            |
 *   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
 *   |            contributing source (CSRC) identifiers             |
 *   :                             ....                              :
 *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *
 */
struct RtpHeader
{
    /* byte 0 */
	//CC(CSRC count): 4bits，表示头部之后contributing sources identifiers的个数。
    uint8_t csrcLen:4;
	//X: 1bit, 表示是否支持Rtp头扩展，置为1的时候，RtpHeader之后会跟1个header extension
    uint8_t extension:1;
	//P: 1bit，表示是否支持填充，为1的时表示在packet的末尾进行填充，方便一些针对固定长度算法的封装。
    uint8_t padding:1;
	//V: 占用2bits，表示版本号。
    uint8_t version:2;

    /* byte 1 */
	//PT: 7bits，playload type表示传输的多媒体类型。
    uint8_t payloadType:7;
	//M: 1bit;对于视频，标记一帧的结束；对于音频，标记会话的开始。
    uint8_t marker:1;
    
    /* bytes 2,3 */
	//sequence number:16bits(2字节)，表示RTP包序号 
    uint16_t seq;
    
    /* bytes 4-7 */
	//timestamp:32bits（4字节），表示时间戳, 必须使用90 kHz 时钟频率
    uint32_t timestamp;
    
	//SSRC:32bits(4字节)，用于标识同步信源，参加同一视频会议的两个同步信源不能有相同的SSRC
    /* bytes 8-11 */
    uint32_t ssrc;
};

struct RtpPacket
{
    struct RtpHeader rtpHeader;
    uint8_t rtppayload[0];
};

class Rtp{
public:
	int isStartCode3(char* buf);
	int isStartCode4(char* buf);
	char* findNextStartCode(char* buf, int len);
	int getOneFrameFromH264File(int fd, char* frame, int size);
	int rtpSendPacket(int socket, const char* ip, int16_t port, struct RtpPacket* rtpPacket, uint32_t dataSize);
	int rtpSendH264Frame(int socket, const char* ip, int16_t port, struct RtpPacket* rtpPacket, uint8_t* frame, uint32_t frameSize);
	void rtpHeaderInit(struct RtpPacket* rtpPacket, uint8_t csrcLen, uint8_t extension, uint8_t padding, uint8_t version, uint8_t payloadType, uint8_t marker, uint16_t seq, uint32_t timestamp, uint32_t ssrc);
};

#endif //_RTP_H_





